// Buffer Class Interface
// (c) jimon game studio

#ifndef JEH_IBUFFER
#define JEH_IBUFFER

#include "jeTypes.h"
#include "jeUnknown.h"

namespace je
{
	namespace core
	{
		//! Buffer Lock Type
		enum BufferLockType
		{
			//! Read Lock Type
			BLT_READ,

			//! Write Lock Type
			BLT_WRITE,

			//! Read and Write Lock Type
			BLT_READWRITE
		};

		//! Buffer Class Interface
		class IBuffer:public je::jeUnknown
		{
		protected:
			//! True if buffer work like stream
			u1 StreamWorkMode;

			//! Temp for save option
			u1 TempStreamWorkMode;

		public:
			//! Constructor
			IBuffer()
				:StreamWorkMode(false),TempStreamWorkMode(false)
			{
			}

			//! Destructor
			virtual ~IBuffer()
			{
			}

			//! Lock Buffer
			virtual void Lock(BufferLockType LockType) = 0;

			//! UnLock Buffer
			virtual void UnLock() = 0;

			//! Return True if locked
			virtual u1 IsLocked() = 0;

			//! Read Data
			virtual void Read(void * Pointer,u32 Bytes) = 0;

			//! Write Data
			virtual void Write(const void * Pointer,u32 Bytes) = 0;

			//! Write Data From Other Buffer
			virtual void WriteFrom(IBuffer * Buffer,u32 Bytes)
			{
				u8 * Temp = NULL;
				JENEW_A(Temp,u8,Bytes)
				Buffer->Read(Temp,Bytes);
				Write(Temp,Bytes);
				JEDELETE_A(Temp)
			}

			//! Allocate Buffer for data,size is count of objects,if already allocated - reallocate with new size
			virtual void Allocate(u32 Bytes) = 0;

			//! DeAllocate Buffer
			virtual void DeAllocate() = 0;

			//! Set Position
			virtual void SetPosition(u32 NewPosition,u1 Relative = false) = 0;

			//! Get Position
			virtual u32 GetPosition() = 0;

			//! Get Size in bytes
			virtual u32 GetSize() = 0;

			//! Get Size of one object
			virtual u32 GetObjectSize() = 0;

			//! Return Object Count
			virtual u32 GetObjectCount()
			{
				return GetSize() / GetObjectSize();
			}

			//! Set Stream Work Mode
			virtual void SetStreamWorkMode(u1 NewMode)
			{
				StreamWorkMode = NewMode;
			}

			//! Get Stream Work Mode
			virtual u1 GetStreamWorkMode()
			{
				return StreamWorkMode;
			}

			//! Save Stream Work Mode Option
			virtual void SaveStreamWorkModeState()
			{
				TempStreamWorkMode = StreamWorkMode;
			}

			//! Restore Stream Work Mode Option
			virtual void RestoreStreamWorkModeState()
			{
				StreamWorkMode = TempStreamWorkMode;
			}

		};
	}
}

#endif
